/**
 * dataProvider
 */

var countProvider = require("./countProvider");
var autoSaveProvider = require("./autoSaveProvider");
var historyProvider = require("./historyProvider");
var storage = require("../../utils/storage");
var consts = require("../../utils/consts");
var tool = require("../../utils/tool");
// var BasePage = require("../model/BasePage");
// var BasePageJump = require("../model/BasePageJump");
// var BasePageTimelines = require("../model/BasePageTimelines");
// var BaseWidget = require("../model/BaseWidget");
// var BaseWidgets = require("../model/BaseWidgets");
// var BasePages = require("../model/BasePages");
// var BaseTimelines = require("../model/BaseTimelines");
// var BaseThreedState = require("../model/BaseThreedState");
var TimelineCreateCommand = require("../command/TimelineCreateCommand");
var TimelineRemoveCommand = require("../command/TimelineRemoveCommand");
var WidgetCreateCommand = require("../command/WidgetCreateCommand");
var WidgetRemoveCommand = require("../command/WidgetRemoveCommand");
var dataProvider = {
    pages: [],
    widgets: [],
    oldWidgets: {},
    timelines: {},
    pageJumpData: {},
    pageTimelines: {},
    deletedWidgetIds: [],
    queryPages: function (page, pagesCallback, widgetsCallback, timelinesCallback) {
        BasePages.query(function (pages) {
            this.pages = pages;
            pagesCallback && pagesCallback(pages);

            if (page && typeof widgetsCallback === "function") {
                this.queryWidgetsByPage(page, widgetsCallback, timelinesCallback);
            }
        }.bind(this));
    },
    queryPageJumpData: function (page, callback) {
        BasePageJump.get(page, function (result) {
            this.pageJumpData = result;
            callback && callback(result);
        }.bind(this));
    },
    queryPageTimelines: function (page, callback) {
        BasePageTimelines.get(page, function (result) {
            this.pageTimelines = result;
            callback && callback(result);
        }.bind(this));
    },
    updatePageTimelines: function (page, an_type, success, error) {
        BasePageTimelines.update(page, an_type, function (result) {
            this.pageTimelines = result;
            success && success(result);
        }.bind(this), function () {
            error && error();
        });
    },
    updatePageJumpData: function (params, success, error) {
        BasePageJump.update(params, function (result) {
            this.pageJumpData = result;
            success && success(result);
        }.bind(this), function (e, err) {
            error && error();
        });
    },
    updatePageData: function (params, success, error) {
        BasePage.update(params, function (result) {
            success && success(result);
        }, function (e, err) {
            error && error();
        });
    },
    defaultPageProperty: function () {
        this.pages.forEach(function (page) {
            page.focus = !!0;
        });
    },
    updateFocusPage: function (page, callback) {
        var _pages = [].slice.call(this.pages);
        for (var i = 0, l = _pages.length; i < l; i++) {
            var pageItem = _pages[i];
            if (pageItem.page_id === page.page_id) {
                pageItem.focus = !0;
            }
            pageItem.title = pageItem.color = i + 1;
        }
        callback && callback(_pages);
    },
    changePage: function (page, pagesCallback, widgetsCallback, timelinesCallback) {
        var _page = $.extend(true, {}, page);
        this.defaultPageProperty();
        this.updateFocusPage(_page, pagesCallback);
        this.queryWidgetsByPage(_page, widgetsCallback, timelinesCallback);

        this.queryPageTimelines(page, function (_pageTimelines) {//更新翻页效果
            storage.data.page_timelines = _pageTimelines;
            storage.data.turning_antype = _pageTimelines[0] ? _pageTimelines[0].an_types[0].an_type : 0;
        });
    },
    getIndexFromPages: function (page) {
        var pages = this.pages;
        for (var i = 0, l = pages.length; i < l; i++) {
            if (page.page_id === pages[i].page_id) {
                return i;
            }
        }
        return -1;
    },
    removeFromPages: function (page) {
        var index = this.getIndexFromPages(page);
        if (index !== -1) {
            this.pages.splice(index, 1);
        }
        //删除页码后重新排序
        var keys = [];
        for (var i = 0,
                 m = this.pages.length; i < m; i++) {
            this.pages[i].title = i + 1;
            keys.push(this.pages[i].page_id);
        }
        if (keys.length)
            BasePages.reorder({
                order: keys,
                reorder: true
            })
        this.updatePages(this.pages);
    },
    addPage: function (success) {
        BasePages.add(function (page) {
            this.pages.push(page);
            success && success(page);
        }.bind(this));
    },
    removePage: function (page, callback) {
        var _page = $.extend(true, {}, page);
        var selectedPage = this.pages[0].page_id == _page.page_id ? this.pages[1] : this.pages[0];

        BasePage.remove(_page.page_id, {
            page_id: _page.page_id
        }, function () {
            this.removeFromPages(_page);
//              if (page.focus){
//                  this.changePage(selectedPage, callback);
//                  return;
//              }
            callback(this.pages);
        }.bind(this));
    },
    getSpecifyPageByPageId: function (page_id) {
        var result = this.pages.filter(function (page) {
            return page.page_id === page_id;
        });
        return result.length ? result[0] : null;
    },
    updatePages: function (pages) {
        if (pages && pages.constructor === Array) {
            this.pages = pages;
        }
    },
    updateOldWidgets: function (widget) {
        this.oldWidgets[widget.id] = widget;
    },
    queryWidgetsByPage: function (page, widgetsCallback, timelinesCallback) {
        BaseWidget.query(page.page_id, function (widgets) {
            tool.addExtraAttrs(widgets);

            this.widgets = widgets;
            widgetsCallback && widgetsCallback(widgets);

            if (typeof timelinesCallback === "function") {
                this.queryCurrentTimelines(timelinesCallback);
            }
        }.bind(this));
    },
    getIndexFromWidgets: function (widget) {
        var widgets = this.widgets;
        for (var i = 0, l = widgets.length; i < l; i++) {
            if (widget.id == widgets[i].id) {
                return i;
            }
        }
        return -1;
    },
    getSpecifyWidgetById: function (widget_id) {
        var result = this.widgets.filter(function (widget) {
            return widget.id === widget_id;
        });
        return result.length ? result[0] : null;
    },
    getTriggerColorByWidgetId: function (widget_id) {
        var widget = this.getSpecifyWidgetById(widget_id);
        if (widget) {
            if (widget.action && widget.action.trigger_color) {
                return widget.action.trigger_color;
            }
        }
    },
    getTriggerColorByTimeline: function (timeline) {
        var triggered_by = timeline.triggered_by || [];
        if (triggered_by.length) {
            return this.getTriggerColorByWidgetId(triggered_by[0]);
        }
    },
    updateLocaleWidget: function (widget, callback) {
        var index = this.getIndexFromWidgets(widget);
        if (index !== -1) {
            this.widgets.splice(index, 1, widget);
        }
        callback && callback(this.widgets);
    },
    saveWidgetPosition: function (page_id, widget, callbackFn) {
        var params = {
            page_id: page_id
        };
        widget.saving = true;
        var callback = function () {
            widget.saving = false;
            widget.urgent = false;
            callbackFn && callbackFn();
        };
        if (widget.urgent) {
            BaseWidget.update(widget, callback);
        } else {
            autoSaveProvider.update(widget, params, callback);
        }
    },
    toggleAll: function (focusWidget, status) {
        var widgets = this.widgets;
        this.widgets.forEach(function (widget) {
            widget.visible = status;
            if (focusWidget.id == widget.id) {
                widget.visible = true;
            }
        });
    },
    addWidgetTypeDisplay: function (widgetType) {
        var types = consts.WIDGET_TYPE;
        var tip_text = '', radius = '0', type_display = widgetType.type_display;
        var widget = widgetType;
        var addType, addTypeDisplay;
        switch (widgetType.type) {
            case types.GRAPH:
                addType = "graph";
                addTypeDisplay = "图形";
                break;
            case types.TEXT:
                addType = "text";
                addTypeDisplay = "文字";
                break;
            case types.PICTURE:
                addType = "picture";
                addTypeDisplay = "图片";
                break;
            case types.VIDEO:
                addType = "video";
                addTypeDisplay = "视频";
                break;
            case types.MUSIC:
                addType = "audio";
                addTypeDisplay = "音乐";
                break;
            case types.THREED:
                addType = "three";
                addTypeDisplay = "3D模型";
                break;
            case types.ALBUM:
                addType = "album";
                addTypeDisplay = "相册";
                break;
            case types.CALLME:
                addType = "call";
                addTypeDisplay = "打电话";
                tip_text = '拨打电话';
                radius = '4';
                break;
            case types.LINK:
                addType = "link";
                addTypeDisplay = "WEB链接";
                tip_text = 'WEB链接';
                radius = '4';
                break;
            case types.NEARBY:
                addType = "nearby";
                addTypeDisplay = "附近搜索";
                tip_text = '附近搜索';
                radius = '4';
                break;
            case types.GEO:
                addType = "geo";
                addTypeDisplay = "导航";
                tip_text = '位置导航';
                radius = '4';
                break;
            case types.EXTEND:
                addType = "extend";
                addTypeDisplay = "拓展介绍";
                tip_text = '拓展介绍';
                radius = '4';
                break;
            case types.APP_DOWNLOAD:
                addType = "app";
                addTypeDisplay = "APP下载";
                tip_text = 'APP下载';
                radius = '4';
                break;
            case types.FIXEDBTN:
                addType = "fixedBtn";
                addTypeDisplay = "浮屏按键";
                tip_text = '';
                radius = '25';
                break;
            case types.REDBAG:
                addTypeDisplay = "AR接红包";
                tip_text = '';
                radius = '0';
                break;
            case types.LOOKERS:
                addTypeDisplay = "围观组件";
                tip_text = '';
                radius = '0';
                break;
            case types.FORM:
                addTypeDisplay = "表单组件";
                addType = "form";
                tip_text = '';
                radius = '4';
                break;
            case types.HOPEBANK:
                addTypeDisplay = "希望金币";
                tip_text = '';
                radius = '0';
                break;
        }
        countProvider.addCount(addType);
        if (consts.ONLYWIDGETTYPE.indexOf(widgetType.type) <= -1) {
            type_display = addTypeDisplay + countProvider.getCount(addType);
        } else {
            type_display = addTypeDisplay;
        }

        return type_display;
    },
    addWidgetTypeToPage: function (page, widgetType, position, obj) {
        var types = consts.WIDGET_TYPE;
        var tip_text = '', radius = '0', type_display = widgetType.type_display;
        var widget = widgetType, action_type = -1;
        if (consts.WIDGET_TYPE_NOT_EQ_ACTION_TYPES.indexOf(widgetType.type) == -1) {
            action_type = widgetType.type;
        }
        if (widgetType.width) {
            position.width = widgetType.width;
        }
        if (widgetType.height) {
            position.height = widgetType.height;
        }
        if (position.width) {
            widgetType.width = position.width;
        }
        if (position.height) {
            widgetType.height = position.height;
        }

        type_display = this.addWidgetTypeDisplay(widget);
        $.extend(true, widget, {
            action: {
                type: action_type,
            },
            position: position,
            unsaved: true,
            custom: 0,
            visible: true,
            tip_text: tip_text,
            radius: radius,
            type_display: type_display
        });
        this.addWidgetToPage(page, widget, null, obj);
    },
    addWidgetToPage: function (page, widget, callback, root, dataProvider, history) {
        widget.offset_z = 0;

        var me = this;

        // 计算最大sort
        var max_sort = this.widgets.length ? (function () {
            for (var i = 0, sort = 0; i < me.widgets.length; i++) {
                sort = Math.max(sort, me.widgets[i].sort || 0);
            }
            return sort;
        })() : 0;

        var initSort = widget.initSort || 0; //处理同时上传多张图片时，sort
        widget.sort = initSort + max_sort + 1;
        delete widget.initSort;

        // 计算最大offset_z
        widget.offset_z = this.widgets.length + initSort;

        // 浮屏按键深度为0
        if (widget.type == consts.WIDGET_TYPE.FIXEDBTN) {
            widget.offset_z = 0;
        }

        if (!widget.form_system) {
            widget.type_display = this.addWidgetTypeDisplay(widget);
        } else {
            widget.type_display = tool.reBuildTypeDisplay(widget);
        }
        BaseWidget.save(widget, page.page_id, function (_widget) {
            me.widgets.forEach(function (widget) {
                widget.focus = false;
            });
            me.widgets.push(_widget);

            tool.addExtraAttrs(me.widgets);

            me.updateWidgetCount(page);
            me.updateDeletedWidgetIds("remove", _widget.id);

            storage.data.selectedWidgetId = _widget.id;
            storage.data.selectedWidgetIds = [_widget.id];

            callback && callback(me.widgets, _widget);
            if (!history) historyProvider.execute(new WidgetCreateCommand(page, _widget, root, dataProvider));
        });
    },
    batchUpdateWidgets: function (widgets, success, error) {
        BaseWidgets.save(widgets, success, error);
    },
    widgetAllVisibleChanged: function (status) {
        this.widgets.forEach(function (widget) {
            widget.visible = status;
        });
    },
    widgetVisibleChanged: function (focusWidget) {//隐藏单个元件
        this.widgets.forEach(function (widget) {
            if (focusWidget.id == widget.id) {
                widget.visible = focusWidget.visible;
            }
        });
    },
    updateWidgetCount: function (page) {
        var count = 0;
        this.pages.forEach(function (page) {
            if (page.id) {
                count++;
            }
        });
        page.widget_count = count;
    },
    updateFromWidgets: function (widget) {
        var index = this.getIndexFromWidgets(widget);
        if (index != -1) {
            this.widgets.splice(index, 1, widget);
        }
    },
    updateSpecifyWidget: function (widget, page_id, callback) {
        BaseWidget.updateWidget(widget, page_id, function () {
            this.updateFromWidgets(widget);
            callback && callback(this.widgets);
        }.bind(this));
    },
    updateWidget: function (widget, callback) {
        BaseWidget.update(widget, function () {
            this.updateFromWidgets(widget);
            callback && callback(this.widgets);
        }.bind(this));
    },
    updateWidgets: function (widgets) {
        if (widgets && widgets.constructor === Array) {
            this.widgets = widgets;
        }
    },
    storageWidgets: function (page, widgets, callback) {
        BaseWidget.updateAll(page.page_id, widgets, function () {
            this.updateWidgets(widgets);
            callback && callback();
        }.bind(this));
    },
    checkValidityByWidgetId: function (id) {
        var index = this.deletedWidgetIds.indexOf(id);
        var widget = this.getSpecifyWidgetById(id);
        var flag = true;
        if (!widget && index === -1) {
            flag = false;
        } else if (widget) {
            var type = widget.action.type;
            // 交互类型不是触发动效
            if (type !== consts.WIDGET_TYPE.TRIGGER) {
                flag = false;
            }
        }
        return flag;
    },
    updateDeletedWidgetIds: function (action, id) {
        var deletedWidgetIds = this.deletedWidgetIds;
        var index = deletedWidgetIds.indexOf(id);
        if (action === "add") {
            if (index === -1) {
                deletedWidgetIds.push(id);
            }
        } else if (action === "remove") {
            if (index !== -1) {
                deletedWidgetIds.splice(index, 1);
            }
            // clear
        } else {
            deletedWidgetIds = [];
        }
    },
    removeFromWidgets: function (widget) {
        var index = this.getIndexFromWidgets(widget);
        if (index !== -1) {
            this.widgets.splice(index, 1);
        }
    },
    removeWidget: function (page, widget, callback, root, dataProvider, history) {
        BaseWidget.delete(widget, page.page_id, function () {
            this.removeFromWidgets(widget);
            this.updateDeletedWidgetIds("add", widget.id);

            callback && callback(this.widgets);
            if (!history) historyProvider.execute(new WidgetRemoveCommand(page, widget, root, dataProvider));
        }.bind(this));
    },
    removeWidgetsByIds: function (page, widgetsIds, callback, root, dataProvider) {
        var ids = [].slice.call(widgetsIds);
        var pedding = ids.length;
        ids.forEach(function (id) {
            var widget = this.getSpecifyWidgetById(id);
            this.removeWidget(page, widget, function () {
                pedding--;
                if (pedding === 0) {
                    callback && callback(this.widgets);
                }
            }.bind(this), root, dataProvider);
        }.bind(this));
    },
    queryCurrentTimelines: function (timelinesCallback) {
        var widgets = this.widgets;
        var pedding = widgets.length;
        if (pedding) {
            this.timelines = {};
            widgets.forEach(function (widget) {
                this.queryTimelinesByWidgetId(widget.id, function () {
                    pedding--;
                    if (pedding == 0) {
                        timelinesCallback && timelinesCallback(this.timelines);
                    }
                }.bind(this));
            }.bind(this));
        }
    },
    getSpecifyTimelineById: function (widget_id, timeline_id) {
        var timelines = this.timelines[widget_id] || [];
        var result = timelines.filter(function (timeline) {
            return timeline.id === timeline_id;
        });
        return result.length ? result[0] : null;
    },
    queryTimelinesByWidgetId: function (widget_id, callback) {
        BaseTimelines.query(widget_id, function (timelines) {
            timelines = this.rebuildTimelineData(timelines);
            this.timelines[widget_id] = timelines;
            callback(timelines);
        }.bind(this));
    },
    rebuildTimelineData: function (timelines) {
        var result = [];

        if (timelines && timelines.constructor === Array) {
            var _timelines = [].slice.call(timelines);

            for (var i = 0, l = _timelines.length; i < l; i++) {
                var timeline = _timelines[i];
                timeline.Top = 8 * i;

                result.push(timeline);
            }
        }

        return result;
    },
    updateSelectedTimeline: function (widget_id, timeline) {
        var timelines = this.timelines[widget_id] || [];
        var _timeline = this.getSpecifyTimelineById(widget_id, timeline.id);
        if (_timeline) {
            var index = timelines.indexOf(_timeline);
            if (index > -1) timelines.splice(index, 1, timeline);
        }
    },
    addTimelineToWidget: function (widget_id, timeline) {
        if (!this.timelines[widget_id]) {
            this.timelines[widget_id] = [];
        }
        this.timelines[widget_id].push(timeline);
    },
    saveTimelineAnimation: function (widget_id, timeline, callbackFn, callbackFnErr, root, history) {
        BaseTimelines.save(widget_id, timeline, function (newTimeline) {
            this.addTimelineToWidget(widget_id, newTimeline);
            if (!history) historyProvider.execute(new TimelineCreateCommand(this, newTimeline, widget_id, root));

            callbackFn && callbackFn(newTimeline);
        }.bind(this), callbackFnErr);
    },
    updateTimelineAnimation: function (widget_id, timeline, callbackFn, callbackFnErr) {
        BaseTimelines.update(widget_id, timeline, function (newTimeline) {
            this.updateTimelineFromWidget(widget_id, newTimeline);
            callbackFn && callbackFn(newTimeline);
        }.bind(this), callbackFnErr);
    },
    removeTimeline: function (widget_id, timeline, successFn, errorFn, root, history) {
        BaseTimelines.remove(widget_id, timeline.id, function () {
            this.removeTimelineFromWidget(widget_id, timeline);
            if (!history) historyProvider.execute(new TimelineRemoveCommand(this, timeline, widget_id, root));

            successFn && successFn();
        }.bind(this), errorFn);
    },
    updateTimelineFromWidget: function (widget_id, timeline) {
        var index = this.timelines[widget_id].indexOf(timeline);
        if (index > -1) this.timelines[widget_id].splice(index, 1, timeline);
    },
    removeTimelineFromWidget: function (widget_id, timeline) {
        var index = this.timelines[widget_id].indexOf(timeline);
        if (index > -1) this.timelines[widget_id].splice(index, 1);
    },
    updateAllTimelines: function (widget_id, timelines, callback) {
        BaseTimelines.updateAll(widget_id, timelines, function () {
            this.timelines[widget_id] = timelines;
            callback && callback(this.timelines);
        }.bind(this));
    },
    reorder: function (from, to) {
        var keys = [], nowWidgets = this.widgets;
        if (!nowWidgets.length) return;
        // anti-moth 1593 nowWidgets顺序与取得from和to值的列表顺序相反
//        from = nowWidgets.length - 1 - from;
//        to = nowWidgets.length - 1 - to;
        nowWidgets.splice(to, 0, nowWidgets.splice(from, 1)[0]);

        for (var i = 0, m = nowWidgets.length; i < m; i++) {
            keys.push(nowWidgets[i].id);
        }
        var newKeys = [];
        for (var j = keys.length - 1; j >= 0; j--) {
            newKeys.push(keys[j]);
        }
        BaseWidget.reorder({
            page_id: this.pages[0].page_id,
            order: newKeys,
            reorder: true
        });
        this.updateWidgets(nowWidgets);
    },
    queryThreedState: function (md5, success, error) {
        return BaseThreedState.queryState(md5, function (result) {
            success && success(result);
        }, function () {
            error && error();
        });
    }
};

module.exports = dataProvider;
